/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.escom.healthlc.controller;

import com.escom.healthlc.business.EcgBusiness;
import com.escom.healthlc.utils.Constantes;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.List;
import java.util.logging.Level;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.chart.CartesianChartModel;
import org.primefaces.model.chart.LineChartSeries;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author Carlos
 */
@ManagedBean(name = "RecognitionPatternController")
@ViewScoped
public class RecognitionPatternController {

    private static final Logger logger = LoggerFactory.getLogger(RecognitionPatternController.class);

    @ManagedProperty("#{EcgBusiness}")
    private EcgBusiness ecgBusiness;

    private CartesianChartModel linearModel;
    private boolean renderUpload;
    private boolean renderChart;
    private List<Double> valuesECG;
    private double spinnerLine;
    private double[][] segmentosSenial;
    private int opcTipoArritmia;
    private int[] opcTipoArritmiaArray;
    private int posAcutal;

    public RecognitionPatternController() {
    }

    @PostConstruct
    private void initRecognitionPatternController() {
        linearModel = new CartesianChartModel();
        renderUpload = true;
        renderChart = false;
        posAcutal = 0;
    }

    public void executeUploadFile(FileUploadEvent evt) {
        logger.debug("Upload");
        try {
            InputStream inputstream = evt.getFile().getInputstream();
            valuesECG = ecgBusiness.crearListValues(inputstream);
            crearGrafica();
        } catch (IOException ex) {
            logger.debug("Error al crear el flujo del libro, descripcion: {}", ex);
        }
        renderUpload = false;
        renderChart = true;
    }

    public void executeSegmentarSenialSupervisado(ActionEvent acEvt) {
        segmentosSenial = ecgBusiness.segmentarSenial(valuesECG, spinnerLine);
        PrintWriter printWriter = null;
        try {
            printWriter = new PrintWriter(new FileWriter(new File("C:\\Users\\Carlos\\Dropbox\\Trabajo Terminal\\Señal\\resultado.txt")));
        } catch (IOException ex) {
            logger.error("Error Logger: {}", ex.getCause().getMessage());
            logger.error("Error Logger: {}", ex.fillInStackTrace().toString());
        }
        opcTipoArritmiaArray = new int[segmentosSenial.length];
        FacesContext facesContext = FacesContext.getCurrentInstance();
        FacesMessage facesMessage;
        facesMessage = new FacesMessage(FacesMessage.SEVERITY_INFO, Constantes.MESSAGE_TITLE, "Segmentación realizada con exito");
        facesContext.addMessage(null, facesMessage);
    }

    public void executeSegmentarSenialNoSupervisado(ActionEvent acEvt) {
//        ecgBusiness.segmentarSenial(valuesECG, spinnerLine);
    }

    public void executeRenderEntrenamiento(ActionEvent acEvt) {
//        ecgBusiness.segmentarSenial(valuesECG, spinnerLine);
        renderUpload = true;
        renderChart = false;
    }

    public void executeRenderAprendizaje(ActionEvent acEvt) {
//        ecgBusiness.segmentarSenial(valuesECG, spinnerLine);
//        renderUpload = true;
//        renderChart = false;
    }

    public void executeSaveSegmentos(ActionEvent acEvt) {
        ecgBusiness.salvarSegmentos(segmentosSenial, opcTipoArritmiaArray);
    }

    public void executeCreateMemoria(ActionEvent acEvt) {
        ecgBusiness.crearMemoriaAsocitiva();
    }

    public void executeRecuperarPatron(ActionEvent acEvt) {
        double[][] segmentos = ecgBusiness.segmentarSenial(valuesECG, spinnerLine);
        List<String> recuperarPatron = ecgBusiness.recuperarPatron(segmentos);
        List<String> coordenadas = ecgBusiness.getCoordenadas();
        linearModel.clear();
        linearModel = new CartesianChartModel();
        LineChartSeries sano = new LineChartSeries();
        LineChartSeries taquicardia = new LineChartSeries();
        LineChartSeries bradicardia = new LineChartSeries();
        LineChartSeries fibrilacion = new LineChartSeries();
        LineChartSeries taquicardiaSupraventricular = new LineChartSeries();
        sano.setLabel("Sano");
        taquicardia.setLabel("Taquicardia");
        bradicardia.setLabel("Bradicardia");
        fibrilacion.setLabel("Fibrilacion Auricular");
        taquicardiaSupraventricular.setLabel("Taquicardia Supraventricular");
        for (int i = 0; i < recuperarPatron.size(); i++) {
            String clasePatron = recuperarPatron.get(i);
            logger.debug("clasePatron {}: ", clasePatron);
            String[] arregloCoordenadas = coordenadas.get(i).split(",");
            int minimoCoordenada = Integer.parseInt(arregloCoordenadas[0]);
            int maximoCoordenada = Integer.parseInt(arregloCoordenadas[1]);
            for (int j = minimoCoordenada; j < maximoCoordenada; j++) {
                if (clasePatron.equals("0")) {
                    sano.set(j, Double.valueOf(valuesECG.get(j)));
                } else {
                    sano.set(j, 0);
                }
                if (clasePatron.equals("1")) {
                    taquicardia.set(j, Double.valueOf(valuesECG.get(j)));
                } else {
                    taquicardia.set(j, 0);
                }
                if (clasePatron.equals("2")) {
                    bradicardia.set(j, Double.valueOf(valuesECG.get(j)));
                } else {
                    bradicardia.set(j, 0);
                }
                if (clasePatron.equals("3")) {
                    fibrilacion.set(j, Double.valueOf(valuesECG.get(j)));
                } else {
                    fibrilacion.set(j, 0);
                }
                if (clasePatron.equals("4")) {
                    taquicardiaSupraventricular.set(j, Double.valueOf(valuesECG.get(j)));
                } else {
                    taquicardiaSupraventricular.set(j, 0);
                }
            }
        }
        linearModel.addSeries(sano);
        linearModel.addSeries(taquicardia);
        linearModel.addSeries(bradicardia);
        linearModel.addSeries(fibrilacion);
        linearModel.addSeries(taquicardiaSupraventricular);
    }

    public void executeNextSegmento(ActionEvent acEvt) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        FacesMessage facesMessage;
        logger.debug("opcTipoArritmia {}: ", opcTipoArritmia);
        opcTipoArritmiaArray[posAcutal] = opcTipoArritmia;
        linearModel = new CartesianChartModel();
        posAcutal++;
        if (posAcutal >= segmentosSenial.length) {
            posAcutal--;
            facesMessage = new FacesMessage(FacesMessage.SEVERITY_WARN, "", "Maximo");
            facesContext.addMessage(null, facesMessage);
        }

        LineChartSeries series1 = new LineChartSeries();
        series1.setLabel("Segmento " + (posAcutal + 1));
        for (int i = 0; i < segmentosSenial[posAcutal].length; i++) {
            series1.set(i, segmentosSenial[posAcutal][i]);
        }
        linearModel.addSeries(series1);
        opcTipoArritmia = opcTipoArritmiaArray[posAcutal];
    }

    public void executePreviousSegmento(ActionEvent acEvt) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        FacesMessage facesMessage;
        logger.debug("opcTipoArritmia {}: ", opcTipoArritmia);
        opcTipoArritmiaArray[posAcutal] = opcTipoArritmia;
        linearModel = new CartesianChartModel();
        posAcutal--;
        if (posAcutal < 0) {
            posAcutal++;
            facesMessage = new FacesMessage(FacesMessage.SEVERITY_WARN, "", "Minimo");
            facesContext.addMessage(null, facesMessage);
        }

        LineChartSeries series1 = new LineChartSeries();
        series1.setLabel("Segmento " + (posAcutal + 1));
        for (int i = 0; i < segmentosSenial[posAcutal].length; i++) {
            series1.set(i, segmentosSenial[posAcutal][i]);
        }
        linearModel.addSeries(series1);
        opcTipoArritmia = opcTipoArritmiaArray[posAcutal];
    }

    public void executePrintLineTop() {
        linearModel.clear();
        crearGrafica();
        LineChartSeries series1 = new LineChartSeries();
        series1.setLabel("Separación");
        series1.set(1, spinnerLine);
        series1.set(valuesECG.size(), spinnerLine);
        linearModel.addSeries(series1);
    }

    public void crearGrafica() {
        LineChartSeries series1 = new LineChartSeries();
        series1.setLabel("D-11");
        logger.debug("Size {} ", valuesECG.size());
        for (int i = 0; valuesECG != null && i < valuesECG.size(); i++) {
            series1.set(i, Double.valueOf(valuesECG.get(i)));
        }
        linearModel.addSeries(series1);
    }

    public void setEcgBusiness(EcgBusiness ecgBusiness) {
        this.ecgBusiness = ecgBusiness;
    }

    public CartesianChartModel getLinearModel() {
        return linearModel;
    }

    public void setLinearModel(CartesianChartModel linearModel) {
        this.linearModel = linearModel;
    }

    public boolean isRenderUpload() {
        return renderUpload;
    }

    public void setRenderUpload(boolean renderUpload) {
        this.renderUpload = renderUpload;
    }

    public boolean isRenderChart() {
        return renderChart;
    }

    public void setRenderChart(boolean renderChart) {
        this.renderChart = renderChart;
    }

    public double getSpinnerLine() {
        return spinnerLine;
    }

    public void setSpinnerLine(double spinnerLine) {
        this.spinnerLine = spinnerLine;
    }

    public int getOpcTipoArritmia() {
        return opcTipoArritmia;
    }

    public void setOpcTipoArritmia(int opcTipoArritmia) {
        this.opcTipoArritmia = opcTipoArritmia;
    }

    public int getPosAcutal() {
        return posAcutal;
    }

    public void setPosAcutal(int posAcutal) {
        this.posAcutal = posAcutal;
    }

}
